package com.qf.service;

import com.qf.config.IdWorker;
import com.qf.constant.CacheConstants;
import com.qf.constant.RabbitMQConstants;
import com.qf.constant.ReportStateConstants;
import com.qf.constant.SourceType;
import com.qf.feign.CacheFeign;
import com.qf.form.SmsInterfaceForm;
import com.qf.model.StandardSubmit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@Service
@Slf4j
public class SmsInterfaceServiceImpl implements SmsInterfaceService {

    @Autowired
    private CacheFeign cacheFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private IdWorker idWorker;

    @Override
    public Map<String, String> checkInterfaceForm(SmsInterfaceForm smsInterfaceForm) {

        Map<String,String> resultMap = new HashMap<>();

        //--------------------1. 校验ClientID-----------------------------------------
        //--------------------101	认证错：clientId错误-----------------------------------------
        //1.1 根据用户传递的clientID去缓存模块查询客户信息
        String clientID = smsInterfaceForm.getClientID();
        Map clientObj = cacheFeign.hMGet(CacheConstants.CACHE_PREFIX_CLIENT + clientID);

        //1.2 判断map集合是否为空以及长度
        if (clientObj == null || clientObj.size() == 0){
            // 根据clientID什么都没查询到
            log.info("【接口模块】 认证错误：clientId错误。  clientID={}",clientID);
            resultMap.put("code", "101");
            resultMap.put("msg", "认证错误，clientId错误");
            return resultMap;
        }

        //---------------------2. 校验pwd-------------------------------------------
        //---------------------102	密码错误----------------------------------------
        //2.1 获取用户输入的pwd
        String pwd = smsInterfaceForm.getPwd();
        //2.2 判断两个pwd是否相等
        if (StringUtils.isEmpty(pwd) || !pwd.equals(clientObj.get("pwd"))){
            log.info("【接口模块】 密码错误: pwd={}",pwd);
            resultMap.put("code", "102");
            resultMap.put("msg", "密码错误");
            return resultMap;
        }

        //---------------------3. 校验ip地址----------------------------------------
        //---------------------103	IP校验错误----------------------------------------
        //3.1 获取用户ip,根据redis中预留的用户ip进行效验
        String ip = smsInterfaceForm.getIp();
        //3.2 从Redis中取出预留的ip地址集合
        String ipAddress = (String)clientObj.get("ipaddress");
        String[] ipArray = ipAddress.split(",");

        //3.3 声明一个标识
        boolean flag = false;
        //3.4 遍历预留的ip地址集合
        if(ipArray != null){
            for (String realIp : ipArray) {
                if (ip.equals(realIp)){
                    //ip地址正确
                    flag = true;
                    break;
                }
            }
        }

        // 3.5判读标记 如果ip地址不正确返回异常信息
        if (!flag){
            log.info("【接口模块】 IP校验错误: ip={}",ip);
            resultMap.put("code", "103");
            resultMap.put("msg", "IP校验错误");
            return resultMap;
        }

        //---------------------4. 校验短信长度----------------------------------------
        //---------------------104	消息长度错，为空或超长（目前定为500个字）----------------------------------------
        //4.1 校验短信长度
        String content = smsInterfaceForm.getContent();
        //4.2 校验非空和长度
        if (StringUtils.isEmpty(content) || content.length() > 500){
            log.info("【接口模块】 消息长度错，为空或超长（目前定为500个字）:  content={}",content);
            resultMap.put("code", "104");
            resultMap.put("msg", "消息长度错，为空或超长（目前定为500个字）");
            return resultMap;
        }

        //---------------------5. 校验手机号----------------------------------------
        //---------------------105	手机号错误----------------------------------------
        //5.1 获取全部手机号
        String mobiles = smsInterfaceForm.getMobile();
        String[] mobileArray = mobiles.split(",");

        //5.2效验手机号个数
        if(mobileArray.length == 0 || mobileArray.length > 100){
            log.info("【接口模块】 手机号错误  mobiles={}",mobiles);
            resultMap.put("code", "105");
            resultMap.put("msg", "手机号错误");
            return resultMap;
        }

        //5.3效验手机号正则
        HashSet<String> errorMobile = new HashSet<>();
        String regex = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
        for (String phone : mobileArray) {
            if (! phone.matches(regex)){
                //有问题的手机号 加入错误手机号集合中
                errorMobile.add(phone);
            }
        }

        //5.4判断错误手机号集合中是否有错误的手机号码字符串
        if(errorMobile.size() > 0){
            log.info("【接口模块】 手机号错误  mobiles={}",mobiles);
            resultMap.put("code", "105");
            resultMap.put("msg", "手机号错误");
            return resultMap;
        }

        //----------------------6. 校验srcID---------------------------------------
        //----------------------106	下行编号（srcID）错误---------------------------------------
        //6.1 获取用户输入的srcID
        String srcIDStr = smsInterfaceForm.getSrcID();
        Long srcID = null;
        if (!StringUtils.isEmpty(srcIDStr)){
            try {
                srcID = Long.parseLong(srcIDStr);
            } catch (NumberFormatException e) {
                log.info("【接口模块】 下行编号（srcID）错误  srcID={}", srcIDStr);
                resultMap.put("code", "106");
                resultMap.put("msg", "下行编号（srcID）错误");
                return resultMap;
            }
        }

        //----------------------7. 如果上述校验全部通过,发送消息到RabbitMQ---------------------------------------
        // 根据手机号发送消息到MQ的队列中进行排队消峰
        // 根据手机号封装短信平台内部使用到的短信对象
        for (String phone : mobileArray) {
            StandardSubmit standardSubmit = new StandardSubmit();

            // sequenceId为submit的唯一标识,需要在这里封装
            standardSubmit.setSequenceId(String.valueOf(idWorker.nextId()));

            //客户端ID
            standardSubmit.setClientID(Integer.parseInt(clientID));
            // 获取当前系统时间
            LocalDateTime localDateTime = LocalDateTime.now();
            //设置短信发送时间
            standardSubmit.setSendTime(new Date());
            //设置短信目的手机号
            standardSubmit.setDestMobile(phone);
            //设置短信发送内容
            standardSubmit.setMessageContent(content);
            //消息的优先级 0 最低 --- 3 最高
            standardSubmit.setMessagePriority(Short.parseShort((String) clientObj.get("priority")));
            //设置短信发送方式为Http
            standardSubmit.setSource(SourceType.HTTP);
            //客户侧唯一序列号
            standardSubmit.setSrcSequenceId(srcID);
            //手机接收的状态值  0 成功 1 等待 2 失败
            standardSubmit.setReportState(ReportStateConstants.WAIT);
            rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND+"_exchange", "routingKey",standardSubmit);
        }


        resultMap.put("code", "0");
        resultMap.put("msg", "接收成功");
        return resultMap;
    }
}
